
//chunkAfter(chuck);
//chunkIsFree();
//chunkToObject();

void primBecome161() //elementsForwardIdentityToEvenIfImmutable:
{
	int arrayA = peek(1);
	int arrayB = peek(0);
	
	if( sizeOf(arrayA) > 0 ) PANIC("Real Become");
	
	forward(arrayA, arrayB, 0);
	
	//BOGUS: verifyHeap();
}

void forward(int arrayA, int arrayB, int twoWay)
{
	while( forwardingTable & 7 != 0 ) forwardingTable++; //make sure it is quadword aligned
	
	forwardingNext = forwardingTable;
	
	int index = sizeOf(arrayA);
	while(index > 0)
	{
		int oopA = slotOf(arrayA, index);
		int oopB = slotOf(arrayB, index);
		
		addForwardEntry(oopA,oopB);
		if(twoWay) addForwardEntry(oopB,oopA);
		
		index--;
	}
	
	updatePointers();
	restoreHeaders();
}

void addForwardEntry(int oopA, int oopB)
{
	printf("%x -> %x\n", oopA, oopB);
	
	int h = *(int*)oopA;
	
	*(int*)forwardingNext = oopB; //new oop
	forwardingNext+=4;
	*(int*)forwardingNext = h; //saved header
	forwardingNext+=4;
	
	h = h & 3; //keep header type;
	h = h | ((forwardingNext-8) >> 1);
	h = h | (1<<31); //set highest bit
	
	*(int*)oopA = h;
}

int remap(int oop)
{
	if( isSmInt(oop) ) return oop; //sm ints are immediate, no remapping
	
	int h = *(int*)oop;
	if( h & (1<<31) ) //Mark bit set
	{
		h = h << 1;
		h = h & 0xFFFFFFF8; //clear 3 lowest bits
		
		return *(int*)h;
	}
	else
	{
		return oop;
	}
}

void updatePointers(/*int allowFreeGaps?*/)
{
	////////////////saveContextRegisters();
	specialObjectsArray = remap(specialObjectsArray);
	true = remap(true);
	false = remap(false);
	nil = remap(nil);
	activeContext = remap(activeContext);
	recycleContext = nil;

	//////////////state in send() and invoke()
	
	for(int object=heapStart;;)
	{
		int header = *(int*)object; int class;
		switch(header&3){
			case 0: //3-word header
				object+=8; 
				class = *(int*)(object-4) >> 2 << 2;
				class = remap(class);
				*(int*)(object-4) = class | 0;
				break;
			case 1: //2-word header
				object+=4;
				class = *(int*)(object-4) >> 2 << 2;
				class = remap(class);
				*(int*)(object-4) = class | 1;
				break;
			case 2: //free space marker
				if(object >= heapNext) goto done;
				PANIC("unexpected free space in updatePointers");
			case 3: //1-word (compact) header
				object+=0; 
				break;
		}
		if(object >= heapNext) PANIC("went past end of heap in updatePointers");
		
		int format = formatOf(object);
		if(format <= 4){ //0...4 - pointer fields
			int nWords = sizeOf(object);
			for(int j=1; j<=nWords; j++){
				int oop = slotOf(object, j);
				if( !isSmInt(oop) ) setSlotOf( object, j, remap(oop) );
			}
		}else if(format >= 12){ //12...15 - compiled methods
			header = slotOf(object, 1);
			int nWords = (header>>10)&255; //number of literals
			for(int j=2; j<=nWords+1; j++){
				int oop = slotOf(object, j);
				if( !isSmInt(oop) ) setSlotOf( object, j, remap(oop) );
			}
		}else if(format >= 8){ //8...11 - bytearrays and strings
		}else{
		}
		object+= (sizeOf(object)*4) + 4;
	}
	
	done:
	return;
	/////////loadContextRegisters();
}

void restoreHeaders()
{
	int oop = firstObject();
	
	while( oop != 0 )
	{
		int h = *(int*)oop;
		if( h & (1<<31) ) //Mark bit set
		{
			h = h << 1;
			h = h & 0xFFFFFFF8; //clear 3 lowest bits
			
			h = *(int*)(h+4);
			*(int*)oop = h;
		}
		
		oop = objectAfter(oop);
	}
}

/*
void mark(int oop, int depth)
{
	if smint, return;
	if marked, return;
	
	if depth > 1000, panic
	
	class and fields do
		mark( it, depth+1 );
}

void sweep()
{
	each chunk do:
		if reachable
			add to forwarding table
		otherwise
			mark free
			join with previous if it is also free
}

void gc()
{
	saveContextRegisters();
	nil recycle context
	
	mark(root, 0);
	sweep();
	updatePointers( 1 );
	moveAndRestoreHeaders();
}
*/
